今天沒有歌曲靈感,只好歌名來湊XD
不過應該昨天點播這首才符合主題
因為多對多關聯的複雜度高,常被視為資料庫設計中的一大挑戰。
當兩個實體間存在多對多關係,要如何有效地表達、以及如何保持其資料的完整性和一致性,都是值得深入探討的議題。今天 Day 19 要來探討背後的設計理念,並透過程式碼範例,解釋如何在 Spring Data JPA 中實現多對多關係~
在用 database 說明多對多前,先用一個簡單的例子來說明。回到過去在學時期學校中的學生和課程,一位學生可以選修多門課程,而一門課程也可以被多位學生選修。在這,學生和課程間的關係就是典型的多對多。
多對多關聯通常在資料庫中透過一個中介表格(join table, junction table or cross-reference table)來實現。這個表包含了多對多這兩個實體的外鍵。以學生&課程為例,會有一個選課表,裡頭記錄學生和課程的關聯資訊。
學生表(Students)
ID
Name
...
課程表(Courses)
ID
CourseName
...
學生課程關聯表(StudentCourses)
StudentID (FK,指向學生表的ID)
CourseID (FK,指向課程表的ID)
在這個結構中,每位學生的每個課程透過「學生課程關聯表」記錄裡表間的關聯,這樣就可以輕鬆查詢某堂課被哪些學生選修,以及一個學生選修了哪些課程。
我們可以使用 @ManyToMany
註解來表示多對多,同時還需要使用 @JoinTable
註解來指定中介表格的資訊。
但需要特別注意 方向性
問題。多對多關聯可以是單向或雙向。多數情況下雙向關聯較為常見,但這也代表在 更新
或 查詢
資料的時候得更加小心確保資料的一致性。
📌以下是書商平台中的「書籍」和「作者」的舉例:
假設我們在經營一個專賣書的電商平台系統,在系統中每本書可能有多位作者,而每位作者也可能寫了多本書,兩者為多對多關係。
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@ManyToMany
@JoinTable(
name = "book_author",
joinColumns = @JoinColumn(name = "book_id"),
inverseJoinColumns = @JoinColumn(name = "author_id"))
private List<Author> authors = new ArrayList<>();
// 省略 getters 和 setters
}
@Entity
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToMany(mappedBy = "authors")
private List<Book> books = new ArrayList<>();
// 省略 getters 和 setters
}
這裡的 book_author
就是多對多關聯的中介表。它包含了 book_id
和 author_id
兩個 FK。
CREATE TABLE book_author (
book_id BIGINT,
author_id BIGINT,
PRIMARY KEY (book_id, author_id),
FOREIGN KEY (book_id) REFERENCES Book(id),
FOREIGN KEY (author_id) REFERENCES Author(id)
);
當我們想要為一本書添加作者時,只需將該作者加入到那本書的 authors
列表中,並保存這本書的實體。
Book book = new Book();
book.setTitle("Spring Boot 實戰");
Author author1 = new Author();
author1.setName("Alice Yang");
Author author2 = new Author();
author2.setName("Bob Chen");
book.getAuthors().add(author1);
book.getAuthors().add(author2);
bookRepository.save(book);
多對多在資料庫設計中是一個不可或缺的部分,但實務上不太建議使用多對多,原因如下:
雖然多對多關係在某些情境下是必要的,但在實務應用中,通常建議透過中介表來管理和簡化這種複雜關係,來達到更好的效能和資料管理。